/*
 * TraceManager.h
 *
 *  Created on: 14 maj 2014
 *      Author: w.antosiewic
 */

#ifndef TRACE_MANAGER_H_
#define TRACE_MANAGER_H_

#include <string>
#include <fstream>
#include <iostream>
#include <pthread.h>
#include <map>
#include "TraceObj.h"
#include "TraceMacros.h"

namespace tsc
{
namespace common
{

enum traceDirection_e
{
  DIRECT_TO_FILE   = -1,
  DIRECT_TO_STDERR =  0,
  DIRECT_TO_STDOUT =  1
};

// Forward declarations
extern const char* traceGroupName[];
class TraceObj;

typedef std::map<std::string, TraceObj*> TraceObjMap;

class TraceManager
{
public:
  static TraceManager* instance();

  ~TraceManager();

  void setProcessName(const char* aName);

  void declareTraceObj(const char* aTraceObjName);
  void enableTraceObj(const char* aTraceObjName, traceGroup_e tg);
  void enableAllTraceObj(const char* aTraceObjName);
  void disableTraceObj(const char* aTraceObjName, traceGroup_e tg);
  void disableAllTraceObj(const char* aTraceObjName);
  bool isTraceObjEnabled(const char* aTraceObjName, traceGroup_e tg);

  void enableTrace(traceGroup_e tg);
  void enableAllTrace();
  void disableTrace(traceGroup_e tg);
  void disableAllTrace();
  bool isTraceEnabled(traceGroup_e tg);

  void setTraceToFile(std::string aFileName);
  void setTraceToStderr();
  void setTraceToStdout();

  const char* doStr(const char *format, ...);

  std::ostream& printTraceHeader(
		  const char*  aFilename,
          int          aLine,
          const char* objName,
          traceGroup_e aTraceGroup);

  const char* processName();

  void lock()
  {
	  pthread_mutex_lock(&_mutex);
  }

  void unlock()
  {
	  pthread_mutex_unlock(&_mutex);
  }

  std::string hexDump(const void* aDataP, int aDataSize);

protected:
  TraceManager();
  const char* timeStamp();

  const char* fileBaseName(const char* filename);
  std::ostream& getStream();

  void setTraceObjState(const char* aTraceObjName, traceGroup_e tg, bool value);
  bool findTraceObj(const char* aTraceObjName, TraceObj*& to);

private:
  static TraceManager*    _instance;
  static const int _traceBufferSize = 1024;
  char             _traceBuffer[_traceBufferSize];
  char             _traceTimeStamp[40];
  bool             _traceState[END_GROUP];
  std::string      _processName;
  std::string      _traceFile;
  traceDirection_e _traceDirection;
  pthread_mutex_t  _mutex;
  std::ofstream*   _OFS; //output file stream
  TraceObjMap      _traceObjMap;
};

} // namespace common
} // namespace tsc


#endif /* TRACE_MANAGER_H_ */
